/**
 * @author kristian
 */

var drawUsingTextureSelected = false;
var drawUsingDecorSelected = false;
var drawUsingPathSelected = false;



var grass = new Image();
grass.src = 'textures/grass.jpg';	    	

var water = new Image();
water.src = 'textures/water2.png';	    	

var dirt1 = new Image();
dirt1.src = 'textures/dirt1.png';	    	

var dirt2 = new Image();
dirt2.src = 'textures/dirt2.png';	    	

var forest1 = new Image();
forest1.src = 'textures/forest1.png';	    	

var forest2 = new Image();
forest2.src = 'textures/forest2.png';

var grain1 = new Image();
grain1.src = 'textures/grain1.png';

var brush1 = new Image();
brush1.src = 'textures/brush1.png';

// COMPASS
var compassImg = new Image();
compassImg.src = 'Compass/Compass-rose_alpha.gif';

// DECOR
var ancient_city = new Image();
ancient_city.src = 'castles/ancient-city.gif';	    	

var ancient_city_walled = new Image();
ancient_city_walled.src = 'castles/ancient-city-walled.gif';

var ancient_town = new Image();
ancient_town.src = 'castles/ancient-town.gif';

var ancient_town_walled = new Image();
ancient_town_walled.src = 'castles/ancient-town-walled.gif';

var cairn = new Image();
cairn.src = 'castles/cairn.gif';

var castle1 = new Image();
castle1.src = 'castles/castle1.gif';

var cathedral1 = new Image();
cathedral1.src = 'castles/cathedral1.gif';

var tower_sage = new Image();
tower_sage.src = 'castles/tower-sage.gif';

var ziggurat = new Image();
ziggurat.src = 'castles/ziggurat.gif';

// ROAD
	    	
var road_horiz = new Image();
road_horiz.src = 'roads/dirt_road_horiz.gif';

var dirt_road_ne_se = new Image();
dirt_road_ne_se.src = 'roads/dirt_road_ne_se.gif';	    	

var dirt_road_nw_sw = new Image();
dirt_road_nw_sw.src = 'roads/dirt_road_nw_sw.gif';	    	

var dirt_road_ne_sw = new Image();
dirt_road_ne_sw.src = 'roads/dirt_road_ne_sw.gif';

var dirt_road_nw_se = new Image();
dirt_road_nw_se.src = 'roads/dirt_road_nw_se.gif';

var dirt_road_nw_ne = new Image();
dirt_road_nw_ne.src = 'roads/dirt_road_nw_ne.gif';

var dirt_road_sw_se = new Image();
dirt_road_sw_se.src = 'roads/dirt_road_sw_se.gif';

// RIVER
var road_horiz = new Image();
road_horiz.src = 'rivers/river_horiz.gif';

var river_ne_se = new Image();
river_ne_se.src = 'rivers/river_ne_se.gif';	    	

var river_nw_sw = new Image();
river_nw_sw.src = 'rivers/river_nw_sw.gif';	    	

var river_ne_sw = new Image();
river_ne_sw.src = 'rivers/river_ne_sw.gif';

var river_nw_se = new Image();
river_nw_se.src = 'rivers/river_nw_se.gif';

var river_nw_ne = new Image();
river_nw_ne.src = 'rivers/river_nw_ne.gif';

var river_sw_se = new Image();
river_sw_se.src = 'rivers/river_sw_se.gif';

var gridSize = {
    sizeX: 5,
    sizeY: 6
}

var gridSize2 = {
    sizeX: 12,
    sizeY: 13
}

var gridSize3 = {
    sizeX: 3,
    sizeY: 3
}

var groundLayer = {};

var initMap = function(layer, gridSize) {
	for (var x=0; x < gridSize.sizeX; x++) {
		var arr = layer['x' + x] = [];
		for (var y = 0; y < gridSize.sizeY; y++) {
			arr.push('water');
		}
	}
}

initMap(groundLayer, gridSize2);

var groundTypeImageMap = {
	'water': water,
	'grass': grass,
	'dirt1': dirt1,
	'dirt2': dirt2,
	'forest1': forest1,
	'forest2': forest2,
	'grain': grain1,
	'brush1': brush1,
	// DECOR
	'ancient-city': ancient_city,
	'ancient-city-walled': ancient_city_walled,
	'ancient-town': ancient_town,
	'ancient-town-walled': ancient_town_walled,
	'cairn': cairn,
	'castle1': castle1,
	'cathedral1': cathedral1,
	'tower-sage': tower_sage,
	'ziggurat': ziggurat,
	
	// ROADS
	'road_horiz': road_horiz,
	'dirt_road_ne_se': dirt_road_ne_se,
	'dirt_road_nw_sw': dirt_road_nw_sw,
	'dirt_road_ne_sw': dirt_road_ne_sw,
	'dirt_road_nw_se': dirt_road_nw_se,
	'dirt_road_nw_ne': dirt_road_nw_ne,
	'dirt_road_sw_se': dirt_road_sw_se,
	// RIVERS
	'road_horiz': road_horiz,
	'river_ne_se': river_ne_se,
	'river_nw_sw': river_nw_sw,
	'river_ne_sw': river_ne_sw,
	'river_nw_se': river_nw_se,
	'river_nw_ne': river_nw_ne,
	'river_sw_se': river_sw_se	
}


var getImage = function(groundType) {
	return groundTypeImageMap[groundType];
}

var textureGrid;

var createGrid = function(options) {
	var gridSize = options.gridSize;	

	var adjust = options.sizeAdjustment || {x: 0, y: 0};
    var adjX = adjust.x || 0;
    var adjY = adjust.y || 0;
	
    // Make the grid
    var sizeX = gridSize.sizeX + adjX;
    var sizeY = gridSize.sizeY + adjY;
    
    return new HEX.Grid(sizeX, sizeY);
}

var init = function(ctx, options){
	
	grid = createGrid(options);
	//options.sizeAdjustment = {x: 1, y:0};
    grid2 = createGrid(options)
    // Get every hex in the grid.
    var area = grid.to_area();
    
    // Get the skeleton (a list of HEX.Boundary objects to draw)
    options.skeleton = area.skeleton(true);
    var fullSkeleton; 
	if (options.textureOn) {
		fullSkeleton = area.fullSkeleton(true);
		options.fullSkeleton = fullSkeleton;
		options.grid = grid;
	}	
	return options;	
    
}

// cache
var gridHexPointsCache = {
};

var drawGrid = function(ctx, options){
    // Draw the grid
    // var scale = 20; // distance between hexes is '1', so scale it up.
    ctx.strokeStyle = options.color;
	var adjust = options.adjustment || {x: 0, y: 0};
    var adjX = adjust.x || 0;
    var adjY = adjust.y || 0;	
	var skeleton = options.skeleton;
	var scale = options.scale;
	var key = 'scale_' + scale.x;

	gridHexPointsCache[key] = []; // init cache	
	
    for (var i = 0; i < skeleton.length; i++) {
        var boundary = skeleton[i];
        // Get a list of points in the boundary.
        var points = boundary.stroke();
		var hexPoints = []; // caching
        // Draw the boundary line.
        ctx.beginPath();
        var x = points[0].x;
        var y = points[0].y;
        var xs = (x + adjX) * scale.x;
        var ys = (y + adjY) * scale.x;
        ctx.moveTo(xs, ys);
				
		hexPoints.push({x: xs, y:ys});
		
        for (var j = 1, jlen = points.length; j < jlen; ++j) {
            var toX = (points[j].x + adjX) * scale.x;
            var toY = (points[j].y + adjY) * scale.x;
            ctx.lineTo(toX, toY);
			hexPoints.push({x: toX, y:toY});			
        }
		ctx.stroke();        		        
		gridHexPointsCache[key].push(hexPoints);
    }
}

function drawText(ctxt,font,size,x,y,text){
  ctxt.translate(x,y);ctxt.mozTextStyle=size+"pt "+font;
  ctxt.mozDrawText(text);ctxt.translate(-1 * x,-1 * y);
  ctxt.fillRect(1,1,1,1);
} //fixes redraw bug

var validPoint = function(h) {
	if (h.i >= 0 && h.i < textureGrid.cols) {
		if (h.j >= 0 && h.j < textureGrid.rows) {
			return true;
		}
	}
	return false;
}

var drawHexCoordinates = function(ctx, options){
	if (!ctx)
		console.log('Error: No context');
    ctx.strokeStyle = options.color;
	var adjust = options.adjustment || {x: 0, y: 0};
    var adjX = adjust.x || 0;
    var adjY = adjust.y || 0;	
	var skeleton = options.skeleton;
	var fullSkeleton = options.fullSkeleton;
	var scale = options.scale;
	ctx.fillStyle    = '#00f';
	ctx.font         = 'italic 30px sans-serif';
	ctx.textBaseline = 'top';
	
	// console.log('Draw Coordinates text');
    for (var i = 0, ilen = skeleton.length; i < ilen; ++i) {

        var boundary = skeleton[i];
		var fullBoundary = fullSkeleton[i];
        // Get a list of points in the boundary.
        // var points = boundary.stroke();
		var points = fullBoundary.stroke()
		// console.log('points:' + points.length);
		try {
			var lastHex = null;
			for (var p = 0; p < points.length; p++) {
				// if only points 0, some hexes go missing!
				var point = points[p];
				var hexPoint = textureGrid.myHexPoint(point);				
				if (validPoint(hexPoint)) {		
					var hex = textureGrid.hexPoint(point);	
					if (!sameHex(hex, lastHex)) {
						lastHex = hex;
						// console.log('i:' + hex.i + ', j:' + hex.j);
						var centerPoint = hex.centre();
						var str = hex.i + ', ' + hex.j;
						var screenX = centerPoint.x * scale.x;
						var screenY = centerPoint.y * scale.x;
						drawText(ctx, ctx.font, 10, screenX - 10, screenY+5, str);
						//drawText(ctx, ctx.font, 10, screenX - 10, 600 - screenY - 215, str);
					}
				} else ('drawHexCoordinates: not valid point');
				
			}
		} catch (e) {
			console.log(e);
		}
    }
}

var drawTextureUsingHex = function(ctx, options){
	if (options) {
		var one_hex_area = new HEX.Area([options.hex]);
		var skeleton = one_hex_area.skeleton(true);
		var fullSkeleton = one_hex_area.fullSkeleton(true);
		// console.log('drawTextureUsingHex');
		for (var i = 0; i < fullSkeleton.length; i++) {
			// console.log('fullSkeleton:' + i);
			var fullBoundary = fullSkeleton[i];
			// console.log(fullBoundary);
			options.fullPoints = fullBoundary.stroke();
			if (drawUsingTextureSelected)
				options.terrainId = terrainSelected;
			else if (drawUsingDecorSelected)
				options.terrainId = decorSelected;
			else if (drawUsingPathSelected)
				options.terrainId = pathSelected;
			if (options.terrainId)
				action = options.terrainId;	
			drawHexTexture(ctx, options);
			options.terrainId = null;
		}
	} else console.log('drawTextureUsingHex: no options');
	
}

var drawTextures = function(ctx, options){
	drawUsingTextureSelected = false;
    // Draw the grid
    // var scale = 20; // distance between hexes is '1', so scale it up.
    ctx.strokeStyle = options.color;
	var adjust = options.adjustment || {x: 0, y: 0};
    var adjX = adjust.x || 0;
    var adjY = adjust.y || 0;	
	var skeleton = options.skeleton;
	var fullSkeleton = options.fullSkeleton;
	var scale = options.scale;
	var textureOn = options.textureOn;
    for (var i = 0; i < skeleton.length; i++) {
		// console.log('skeleton:' + i);        
		var fullBoundary = fullSkeleton[i];		
        // Get a list of points in the boundary.        
        if (textureOn) {
			var fullPoints = fullBoundary.stroke();			
			if (fullPoints) {
				// console.log('fullpoints:' + fullPoints.length);
				var lastHex = null;	
				for (var p = 0; p < fullPoints.length; p++) {				
					options.fullPoints = fullPoints;
					var point = fullPoints[p];
					var hexPoint = textureGrid.myHexPoint(point);
					if (validPoint(hexPoint)) {					
						// console.log(point);
						var hex = textureGrid.hexPoint(point);
						if (!sameHex(hex, lastHex)) {
							// console.log('new hex');
							lastHex = hex;
							options.hex = hex;
							// console.log(hex);
							drawTextureUsingHex(ctx, options);
						}
					} // else ('drawTextures: not valid point');
				}
			}
        } 
    }
}

var drawCompass = function (ctx) {
	var margin = 10;
	var compassSize = {
		width: 100,
		height: 100
	};
	var position_NW = {x: margin, y: margin}; 
	var position_NE = {x: 600 - margin - compassSize.width, y: margin}; 	
	var position_SW = {x: margin, y: 600 - margin - compassSize.height}; 	
	var position_SE = {x: 600 - margin - compassSize.width, y: 600 - margin - compassSize.height}; 	
	var position; 
	switch (compass_corner) {
		case 'NW': position = position_NW; break;		
		case 'NE': position = position_NE; break;
		case 'SE': position = position_SE; break;
		case 'SW': position = position_SW; break;
		default: position = position_SW;
	}
	console.log(position);
	console.log(compassSize);
	ctx.drawImage(compassImg, position.x, position.y, compassSize.width, compassSize.height);	
}

var drawHexTexture = function(ctx, options) {
	// console.log('drawHexTexture');	
	ctx.save();			
	options.points = options.fullPoints;
	clipGrid(ctx, options); 
	//options.points = options.points;		
	var hex = drawTextureImage(ctx, options);  
	ctx.restore();	                             	
}

var getAreaAroundHex =function(hex, range) {
	return HEX.fill( HEX.range(h,range) );	
}





// var centerPoint = hex.centre();

var getDrawOptions = function(options){
	var points = options.points;
	var scale = options.scale;
	var adjust = options.adjustment || {x: 0, y: 0};
    var adjX = adjust.x || 0;
    var adjY = adjust.y || 0;    
    var x = points[0].x;
    var y = points[0].y;
    var xs = Math.round((x + adjX -1) * scale.x);
    var ys = Math.round((y + adjY - 0.29) * scale.x);	
	return {x: xs, y: ys};	
}

var drawTextureImage = function(ctx, options){
	var points = options.points;
	var scale = options.scale;
	try {	
		// console.log(points[0]);
		var hex = options.hex || textureGrid.hexPoint(points[0]);
		// console.log(hex);
		var position = getDrawOptions(options);
		var h_i = hex.i;
		var h_j = hex.j;	
		var groundType = options.terrainId || null;
		var index_x = 'x' + h_i;
		// console.log('[drawTextureImage] i:' + h_i + ', j:' + h_j + ', index_x:' + index_x);
		if (!groundType) {			
			var groundArr = groundLayer[index_x];
			if (h_j < groundArr.length)
				groundType = groundArr[h_j];	
			else groundType = 'water';	
		} else {
			// remove from groundLayer at position j
			groundLayer[index_x][h_j] = groundType;
			// console.log('groundLayer: x=' + index_x + ', j=' + h_j + ' type:' + groundType);
		}
		
		var img = getImage(groundType);
		// console.log('type:' + groundType);
		// console.log(img);
		if (img && position)
		    ctx.drawImage(img, position.x, position.y, scale.x, scale.y);
	} catch (e) {
		console.log(e);
	}			

}

var clipGrid = function(ctx, options){
	var points = options.points;
	var scale = options.scale;
	var adjust = options.adjustment || {x: 0, y: 0};	
	ctx.color = "rgba(255,0,0,0.5)";
	var adjX = adjust.x || 0;
	var adjY = adjust.y || 0;

    // Make clip region
    ctx.beginPath();
    var x = points[0].x;
    var y = points[0].y;
    var xs = (x + adjX) * scale.x;
    var ys = (y + adjY) * scale.x;
    ctx.moveTo(xs, ys);
    for (var j = 1, jlen = points.length; j < jlen; ++j) {
        var toX = (points[j].x + adjX) * scale.x;
        var toY = (points[j].y + adjY) * scale.x;
        ctx.lineTo(toX, toY);
    }
	//ctx.stroke();
    ctx.clip();
	
}




